﻿using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.SignalR;
using TrackSystem.Contracts;
using TrackSystem.EmailService;
using TrackSystem.Entities.Dtos.User;
using TrackSystem.Entities.Models;

namespace TrackSystem.API.SignalRHub
{

    /// <summary>
    /// Track Signalr类
    /// </summary>
    /// <param name="wrapper"></param>
    /// <param name="userManager"></param>
    /// <param name="mapper"></param>
    /// <param name="signInManager"></param>
    public partial class TrackHub(IRepositoryWrapper wrapper,
        UserManager<User> userManager,
        IMapper mapper,
        //IEmailSender emailSender,
        SignInManager<User> signInManager
        ) : Hub
    {

        /// <summary>
        /// 获取所有的变量名称
        /// </summary>
        /// <returns></returns>
        public async Task GetVarNames()
        {
            var regs = await wrapper.Var.GetAllListAsync();
            List<string> names = (from reg in regs 
                    let c = reg.ReadOnly? 'R' : 'W' 
                    select $"{reg.Name}|{reg.DataType.ToString()[0]}{c}")
                .ToList();
            await Clients.Caller.SendAsync("RecvVarNames", names);
        }

        /// <summary>
        /// 用户登录访问
        /// </summary>
        /// <param name="userEmail">用户名</param>
        /// <param name="userPassword">用户密码</param>
        /// <param name="rememberMe">用户密码</param>
        /// <returns></returns>
        public async Task Login(string userEmail, string userPassword, bool rememberMe)
        {
            var result = await signInManager.PasswordSignInAsync(userEmail, userPassword, rememberMe, true);
            
            if (result.IsLockedOut)
            {
                await Clients.Caller.SendAsync("RecvLogin", ApiResult<UserDto>.Fail($"{DateTime.Now} 用户已被锁定"));
                return;
            }

            if (!result.Succeeded)
            {
                await Clients.Caller.SendAsync("RecvLogin", ApiResult<UserDto>.Fail($"{DateTime.Now} 无效的用户名或者密码"));
                return;
            }

            var user = await userManager.FindByEmailAsync(userEmail);
            if (user != null)
            {
                 var userDto = mapper.Map<UserDto>(user);
                 userDto.Role = string.Join(',', await userManager.GetRolesAsync(user));
                 await Clients.Caller.SendAsync("RecvLogin", ApiResult<UserDto>.Ok(userDto));               
            }
        }

        /// <summary>
        /// 忘记密码处理函数
        /// </summary>
        /// <param name="forgotPasswordDto"></param>
        /// <returns></returns>
        public async Task ForgotPassword(ForgotPasswordDto forgotPasswordDto)
        {
            var user = await userManager.FindByEmailAsync(forgotPasswordDto.Email);
            if (user == null)
            {
                await Clients.Caller.SendAsync("RecvForgotPassword", ApiResult<ForgotPasswordDto>.Fail($"电子邮箱{forgotPasswordDto.Email}不存在"));
                return;
            }

            var token = await userManager.GeneratePasswordResetTokenAsync(user);
            var message = new Message(user.UserName ??= "", user.Email ??= "", "重置密码", token);
            //await emailSender.SendEmailAsync(message);
            await Clients.Caller.SendAsync("RecvForgotPassword", ApiResult<ForgotPasswordDto>.Ok(forgotPasswordDto,
                $"重置密码邮件已发送至{forgotPasswordDto.Email}"));
        }


        /// <summary>
        /// 重置密码处理函数
        /// </summary>
        /// <param name="resetPasswordDto"></param>
        /// <returns></returns>
        public async Task ResetPassword(ResetPasswordDto resetPasswordDto)
        {
            var user = await userManager.FindByEmailAsync(resetPasswordDto.Email);
            if (user == null)
            {
                await Clients.Caller.SendAsync("RecvResetPassword", ApiResult<ResetPasswordDto>.Fail($"电子邮箱{resetPasswordDto.Email}不存在"));
                return;
            }
            var result = await userManager.ResetPasswordAsync(user, resetPasswordDto.Token, resetPasswordDto.Password);
            if (!result.Succeeded)
            {
                await Clients.Caller.SendAsync("RecvResetPassword", ApiResult<ResetPasswordDto>.Fail("重置密码失败"));
                return;
            }
            await Clients.Caller.SendAsync("RecvResetPassword", ApiResult<ResetPasswordDto>.Ok(resetPasswordDto, "重置密码成功"));
        }

        /// <summary>
        /// 添加数据表
        /// </summary>
        /// <returns></returns>
        public async Task InsertRecordTable(string recName)
        {
            try
            {
                wrapper.InsertRecordTable(recName);
                await Clients.Caller.SendAsync("RecvInsertRecord", ApiResult<string>.Ok("数据表创建成功"));
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("RecvInsertRecord", ApiResult<string>.Fail($"数据表创建失败: {ex.Message}"));
            }
        }
    }
}
